feat: Bitwarden secret resolver and async register#398
feat: Bitwarden secret resolver and async register#398Coke1120 wants to merge 4 commits intoCortexReach:masterfrom
Conversation
Review: REQUEST-CHANGESThe Bitwarden secret resolver addresses a real operational gap (issue #349). Two issues need fixing before merge: Must fix:
Worth considering (not blocking):
|
AliceLJY
left a comment
There was a problem hiding this comment.
Thanks for the Bitwarden integration and the async register refactor — the architecture is sound overall. A few things to confirm before merging:
-
Potentially stale test comment:
test/session-summary-before-reset.test.mjshas a comment "register() is sync; before_reset is available immediately" — this seems to contradict the async change. Could you verify this test still passes and update the comment if it's outdated? -
Silent failure on initPromise rejection: When
initFailed = true, all hooks silently skip without any warning to the user. For a secrets resolution failure this feels too quiet — would you consider at least logging awarnwhen a hook is skipped due to init failure, so users know why memory isn't working? -
Test checklist:
test/secret-resolver.test.mjsandnpm testare still unchecked — please confirm all tests pass before we merge.
Happy to approve once these are addressed!
Add src/secret-resolver.ts supporting ${ENV_VAR} and bws://<secret-id>
Bitwarden CLI secret references for embedding, rerank, and LLM API keys.
Make plugin register() async to support async secret resolution.
Update openclaw.plugin.json docs to advertise bws:// support.
Fix all tests to await plugin.register().
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
With async register() now awaited, selfImprovement defaults to enabled and registers command:new before the sessionMemory assertion runs. Explicitly disable it in the base test config to isolate the assertion. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…t resolution
Make register() synchronous again (OpenClaw loader does not await it).
All hook/tool registrations happen immediately; embedder, retriever, and
smartExtractor are initialized in a fire-and-forget initPromise that
resolves async secrets. Every hook that uses these awaits initPromise
before proceeding. register() returns initPromise so awaiting callers
(tests, host implementations that do support async) can still wait.
Also fix:
- bws access token passed via BWS_ACCESS_TOKEN env var instead of
--access-token CLI arg to avoid exposure in process listings
- embedder double-resolveEnvVars: skip expansion if key lacks ${}
- selfImprovement: { enabled: false } in sessionDefaultApi,
sessionEnabledApi, and session-summary harness to isolate assertions
from the now-default-true selfImprovement feature
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ment When secret resolution fails, service.start() now logs a visible warn explaining why memory hooks are disabled, instead of silently skipping. Update stale comment in session-summary test: register() returns initPromise so awaiting it is meaningful, not just a sync guard. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fc782a2 to
5fb9de7
Compare
Summary
src/secret-resolver.tssupporting${ENV_VAR}andbws://<secret-id>Bitwarden Secrets Manager refs for embedding, rerank, and LLM API keysregister()stays synchronous; async secret resolution runs ininitPromise. Hooks await it before use;register()returnsinitPromiseso callers that do await (tests, future host support) can wait for full initservice.start()logs a clear warn if secret resolution failed, so users know why memory is unavailableBWS_ACCESS_TOKENenv var instead of--access-tokenCLI arg to avoid process listing exposureresolveEnvVarsin embedder for already-resolved keysopenclaw.plugin.jsondocs to advertisebws://support on all API key fieldsawait plugin.register()and addselfImprovement: { enabled: false }to test configs that assertcommand:new === undefinedTest plan
node --test test/secret-resolver.test.mjs— verify Bitwarden and env-var resolution pathsnpm test— full test suite passesSplit from #349.
🤖 Generated with Claude Code